/**
 * 
 */
package com.ra.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.da.landlord.DaAgreement;
import com.googlecode.cswish.exception.ApplicationException;
import com.ra.landlord.Agreement;

/**
 * @author colin
 * @date 2014年9月5日
 */
public class DateTimeUtil {
	
	private static final Log logger = LogFactory.getLog(DateTimeUtil.class);
	
	/** 带年月日时分秒的日期时间格式字符串: yyyy-MM-dd HH:mm:ss */
    public final static String ISO_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /** 带年月日的日期格式字符串1: yyyy-MM-dd */
    public final static String ISO_DATE_FORMAT = "yyyy-MM-dd";
    
    /** 带年月日的日期格式字符串1: yyyy-MM-dd */
    public final static String ISO_MONTH_FORMAT = "yyyy-MM";
    
    /** 带年月日的日期格式字符串2: yyyy/MM/dd */
    public final static String ISO_DATE_FORMAT_SLASH = "yyyy/MM/dd";
    
    public final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(ISO_DATE_FORMAT);
    
    public final static SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat(ISO_DATETIME_FORMAT);
    
    public final static SimpleDateFormat DATE_FORMAT_SLASH = new SimpleDateFormat(ISO_DATE_FORMAT_SLASH);
	
	/**
	 * 私有構造函數
	 */
	private DateTimeUtil() {
		
	}
	
	/**
     * 根据日期格式yyyy-MM-dd来获取指定的对象的字符串信息
     * 
     * @param value 需要被转换的日期时间对象引用
     * @return 返回的是格式化后的字符串
     */
    public static String formatDate(Date value) {
        return formatDateTime(value, null);
    }
    
    /**
     * strDate 按照格式转换为时间字符串
     * @param strDate
     * @param format
     * @return
     */
    public static String formatStringDate(String strDate, String format){
    	String formatDate = "";
    	if (StringUtils.isNotBlank(strDate)) {
    		Date date = DateTimeUtil.StrToDate(strDate);
    		formatDate = DateTimeUtil.formatDateTime(date,format);
		}
    	return formatDate;
    }
    
    /**
     * 获取两个时间的间隔天数
     * @param strDate
     * @param format
     * @return
     */
    public static long getIntervalDays(String beginDate, String endDate){
    	long num = 0;
    	if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
    		beginDate = formatStringDate(beginDate, ISO_DATE_FORMAT);
    		endDate = formatStringDate(endDate, ISO_DATE_FORMAT);
    		Date dateBeginDate = StrToDate(beginDate,DATE_FORMAT);
    		Date dateEndDate = StrToDate(endDate,DATE_FORMAT);
    		if (dateEndDate != null && dateEndDate != null) {
	    		num = (dateEndDate.getTime()-dateBeginDate.getTime())/(24*60*60*1000);
	    		if (dateEndDate.after(dateBeginDate)) {
	    			++num;
				}else{
					--num;
				}
    		}
		}
    	return num;
    }
    
    /**
     * 获取两个时间的间隔天数
     * @param strDate
     * @param format
     * @return
     */
    public static int getIntervalDays(Date beginDate, Date endDate){
    	return (int)((endDate.getTime() - beginDate.getTime()) / (1000 * 60 * 60 * 24));
    }
    
    /**
	* 字符串转换成日期
	* @param str
	* @return date
	*/
	public static Date StrToDate(String str) {
		return StrToDate(str,DATE_FORMAT);
	}
	
	/**
	 * 日期补全
	 * @param date
	 * @return
	 */
	public static String completeDateTime(String date){
		String dateTime = date;
		if(date != null && date.length() == 10){
			dateTime += " 00:00:00";
		}
		return dateTime;
	}
	
	public static String completeDateTimeNew(String date){
		Date toDate = StrToDate(date);
		return formatDate(toDate);
	}
	
    /**
	* 字符串转换成日期
	* @param str
	* @param format
	* @return date
	*/
	public static Date StrToDate(String str,SimpleDateFormat format) {
		
		Date date = null;
		if (str == null || str.length() == 0) {
			return null;
		}

		SimpleDateFormat secondFormat = null;
		if(format != null){
			try {
				date = format.parse(str);
			} catch (ParseException e) {
				if(str.length() == 10){
					secondFormat = DATE_FORMAT;
				}else if(str.length() == 19){
					secondFormat = DATETIME_FORMAT;
				}
				if (secondFormat != null) {
					try {
						date = secondFormat.parse(str);
					} catch (ParseException e1) {
						logger.debug("second parse date error again", e);
					}
				}
			}
		}
		
		return date;
	}
    
    /**
     * 根据指定的日期时间格式来获取指定的对象的字符串信息
     * 
     * @param value 需要被转换的日期时间对象引用
     * @param format 指定的日期时间格式,为空时将使用默认的日期时间格式yyyy-MM-dd HH:mm:ss
     * @return 返回的是格式化后的字符串
     */
    public static String formatDateTime(Date value, String format) {
        if (value == null) {
            return "";
        }
        String strFormatStyle = StringUtils.isEmpty(format) ? ISO_DATETIME_FORMAT : format;
        SimpleDateFormat objSimpleDateFormat = new SimpleDateFormat(strFormatStyle);
        return objSimpleDateFormat.format(value);
    }
    
    /**
     * 
     * 根据身份证号生成出生日期
     * @param cardID 15位或18位的身份证号
     * @return 出生日期
     * @throws ApplicationException 
     *
     */
	public static Date getBirthday(String cardID) {
		Date birthdayDate = null;
		StringBuffer tempStr = null;
		if (cardID != null && cardID.trim().length() > 0) {
			if (cardID.trim().length() == 15) {
				tempStr = new StringBuffer(cardID.substring(6, 12));
				tempStr.insert(4, '-');
				tempStr.insert(2, '-');
				tempStr.insert(0, "19");
			} else if (cardID.trim().length() == 18) {
				tempStr = new StringBuffer(cardID.substring(6, 14));
				tempStr.insert(6, '-');
				tempStr.insert(4, '-');
			}
		}
		if (tempStr != null && tempStr.toString().trim().length() > 0) {
			try {
				birthdayDate = DATE_FORMAT.parse(tempStr.toString());
			} catch (Exception e) {
				//throw new ApplicationException("输入的身份证错误，不能转换为相应的出生日期，身份证ID："+cardID,e);
				logger.warn("输入的身份证错误，不能转换为相应的出生日期，身份证ID："+cardID,e);
			}
		}
		return birthdayDate;
	}
	
	/**
     * 
     * 根据起租时间和租期，算到期时间，要求开始日期为2013/02/12或2013-02-12格式
     * @param beginDate 
     * @param rentPeriod
     * @return 到期时间
     *
     */
	public static String getEndDate(String beginDate, int rentPeriod) {
		Date begin = null;
		String endDate = null;
		GregorianCalendar gregorianCalendar = null;
		try {
			if (beginDate.indexOf("/") > -1) {
				begin = DATE_FORMAT_SLASH.parse(beginDate);
			}else if(beginDate.indexOf("-") > -1){
				begin = DATE_FORMAT.parse(beginDate);
			}
			if (begin != null) {
				String[] beginArr = beginDate.split("/|-");
				if (beginArr != null && beginArr.length >= 3) {
					gregorianCalendar = new GregorianCalendar(Integer.valueOf(beginArr[0]),Integer.valueOf(beginArr[1]),Integer.valueOf(beginArr[2]));
					gregorianCalendar.add(Calendar.MONTH, rentPeriod-1);
					endDate = DATETIME_FORMAT.format(gregorianCalendar.getTime());
				}
			}
		} catch (Exception e) {
			throw new ApplicationException("计算租期到期时间有误，beginDate："+beginDate+",rentPeriod:"+rentPeriod,e);
		}
		return endDate;
	}
	
    /**
     * 根据日期获得所在周的日期 
     * @param mdate
     * @return
     */
	public static List<Object> dateToWeek(Date mdate) {
		Calendar calendar = Calendar.getInstance();
		int b = calendar.get(Calendar.DAY_OF_WEEK);
		Date fdate;
		List<Object> list = new ArrayList<Object>();
		Long fTime = mdate.getTime() - b * 24 * 3600000;
		for (int a = 1; a <= 7; a++) {
			fdate = new Date();
			fdate.setTime(fTime + (a * 24 * 3600000));
			list.add(a - 1, new Timestamp(fdate.getTime()));
		}
		return list;
	}
	
	/**
	 * 根据当前日期获取所在周的第一天
	 * @param mdate
	 * @return
	 */
	public static Date getFirstDayOfWeek(Date mdate) {
		Calendar calendar = Calendar.getInstance();
		int b = calendar.get(Calendar.DAY_OF_WEEK);
		calendar = DateUtils.truncate(calendar, Calendar.DATE);
		Long fTime = mdate.getTime() - b * 24 * 3600000;
		Date fdate = new Date(fTime + (1 * 24 * 3600000));
		return fdate;
	}
	
	/**
	 * 根据当前日期获取所在周的最后一天
	 * @param mdate
	 * @return
	 */
	public static Date getEndDayOfWeek(Date mdate) {
		Calendar calendar = Calendar.getInstance();
		int b = calendar.get(Calendar.DAY_OF_WEEK);
		calendar = DateUtils.truncate(calendar, Calendar.DATE);
		Long fTime = mdate.getTime() - b * 24 * 3600000;
		Date fdate = new Date();
		fdate.setTime(fTime + (8 * 24 * 3600000));
		return fdate;
	}
	
	/**
	 * 根据年份获取当年所有周末的日期
	 * @param year
	 */
	public static List<Calendar> getCalendarsByYear(int year) {
        Calendar calendar = new GregorianCalendar(year, 0, 1);
        int i = 1;
        List<Calendar> calendars = new ArrayList<Calendar>();
        while (calendar.get(Calendar.YEAR) < year + 1) {
            calendar.set(Calendar.WEEK_OF_YEAR, i++);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
            if (calendar.get(Calendar.YEAR) == year) {
            	calendars.add(calendar);
                //System.out.printf("星期天：%tF%n", calendar);
            }
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
            if (calendar.get(Calendar.YEAR) == year) {
            	calendars.add(calendar);
                //System.out.printf("星期六：%tF%n", calendar);
            }
        }
        return calendars;
	}
	
	/** 
     * 获得指定日期的后一天 
     *  
     * @param specifiedDay 
     * @return 
     */  
    public static String getSpecifiedDayAfter(String specifiedDay) {  
        Calendar c = Calendar.getInstance();  
        Date date = null;  
        try {  
            date = DATETIME_FORMAT.parse(specifiedDay);  
        } catch (ParseException e) {
        	logger.error("根据指定日期时间获取下一天日期时间出错，指定日期时间："+specifiedDay);
        }  
        c.setTime(date);  
        int day = c.get(Calendar.DATE);  
        c.set(Calendar.DATE, day + 1);  
  
        String dayAfter = DATETIME_FORMAT.format(c.getTime());  
        
        return dayAfter;  
    }  
    
    /**   
     * 计算两个日期之间相差的天数   
     * @param date1   
     * @param date2   
     * @return   
     */    
    public static int daysBetween(Date date1,Date date2){     
        Calendar cal = Calendar.getInstance();
        cal.setTime(date1);
        long time1 = cal.getTimeInMillis(); 
        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        return Integer.parseInt(String.valueOf(between_days));     
    }
    
    /**   
     * 计算两个日期之间相差的天数   
     * @param date1   
     * @param date2   
     * @return   
     */    
    public static String getDate(Calendar calendar){
    	Date date = calendar.getTime();
    	return formatDateTime(date, "MM-dd");
    }
    
    public static String getFeeEndDate(String dateBeginRecv, Integer rentCycle) {
    	Date start = null;
    	try {
    		start = DATETIME_FORMAT.parse(dateBeginRecv);
    	} catch (ParseException e) {
    		try {
				start = DATE_FORMAT.parse(dateBeginRecv);
			} catch (ParseException e1) {
				logger.error("获取fee的技术日期，格式化日期失败，非法日期：", e1);
			}
    	}
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(start);
    	calendar.add(Calendar.MONTH, rentCycle);
    	calendar.add(Calendar.DATE, -1);
    	return DATETIME_FORMAT.format(calendar.getTime());
    }
    
    public static Date getFeeEndDate(Date dateBeginRecv, Integer rentCycle) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(dateBeginRecv);
    	calendar.add(Calendar.MONTH, rentCycle);
    	calendar.add(Calendar.DATE, -1);
    	return calendar.getTime();
    }
    
    public static Date getOneDayAfter(Date dateBeginRecv) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(dateBeginRecv);
    	calendar.add(Calendar.DATE, 1);
    	return calendar.getTime();
    }
    
    public static Date throwTimeForDate(Date now) {
    	try {
			now = DATE_FORMAT.parse(DATE_FORMAT.format(now));
		} catch (ParseException e) {
			logger.error("日期去掉时间部分失败！", e);
		}
    	return now;
    }
    
    public static Date GetDateWithAdvanceNum(Date now, Integer advanceNum) {
    	if (advanceNum == null) {
    		advanceNum = 3;
    	}
    	now = throwTimeForDate(now);
    	Calendar advanceCalendar = Calendar.getInstance();
    	advanceCalendar.setTime(now);
    	advanceCalendar.add(Calendar.DATE, advanceNum * -1);
    	return advanceCalendar.getTime();
    }
    
    /** 
     * 获得本月的开始时间，即2012-01-01 00:00:00 
     *  
     * @return 
     */  
    public static Date getCurrentMonthStartTime() {  
        Calendar c = Calendar.getInstance();  
        Date currentMonthStartTime = null;  
        SimpleDateFormat shortSdf = new SimpleDateFormat(ISO_DATE_FORMAT);  
        try {  
            c.set(Calendar.DATE, 1);  
            currentMonthStartTime = shortSdf.parse(shortSdf.format(c.getTime()));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return currentMonthStartTime;  
    }  
    
    /** 
     * 当前月的结束时间，即2012-01-31 23:59:59 
     *  
     * @return 
     */  
    public static Date getCurrentMonthEndTime() {  
        Calendar c = Calendar.getInstance();  
        Date currentMonthEndTime = null;  
        SimpleDateFormat shortSdf = new SimpleDateFormat(ISO_DATE_FORMAT);  
        try {  
            c.set(Calendar.DATE, 1);  
            c.add(Calendar.MONTH, 1);  
            c.add(Calendar.DATE, -1);  
            currentMonthEndTime = shortSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return currentMonthEndTime;  
    }  
}
